package com.example.library.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.example.library.common.Result;
import com.example.library.entity.Book;
import com.example.library.entity.BorrowRecord;
import com.example.library.service.IBookService;
import com.example.library.service.IRecordService;
import com.example.library.utils.TokenUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

/**
 * 书籍管理
 *
 * 该控制器处理书籍的相关操作，如获取书籍列表、添加书籍、删除书籍等。
 *
 * 同时对每个操作进行 Token 验证，确保只有经过授权的用户才能进行操作。
 */
@RestController
@CrossOrigin("*")
@RequestMapping( "/book")
@Validated
public class BookController {

    @Autowired
    private IBookService iBookService; // 注入书籍服务类

    @Autowired
    private TokenUtil tokenUtil; // 注入 Token 工具类，用于 Token 验证

    @Autowired
    private IRecordService iRecordService; // 注入借阅记录服务类

    /**
     * 获取所有书籍
     *
     * 该方法用于获取系统中所有书籍的列表。
     *
     * @param authorizationHeader 请求头中的授权信息，包含 JWT Token
     * @return 包含书籍列表的 Result 对象
     */
    @GetMapping("/all")
    public Result<List> getAllBooks(@RequestHeader("Authorization") String authorizationHeader) {
        // 验证 Token 是否有效
        Result tokenResult = tokenUtil.validateToken(authorizationHeader);
        if (!tokenResult.isSuccess()) {
            return Result.error(401, "Token is invalid or expired");
        }

        // 获取所有书籍列表
        List<Book> list = iBookService.list();
        return Result.success(list); // 返回成功结果
    }

    /**
     * 添加书籍
     *
     * 该方法用于添加新书籍到系统中，操作之前会进行 Token 验证。
     *
     * @param authorizationHeader 请求头中的授权信息，包含 JWT Token
     * @param book 要添加的书籍对象
     * @return 添加操作的结果
     */
    @PostMapping("/addbook")
    public Result addBook(@RequestHeader("Authorization") String authorizationHeader, @RequestBody @Validated Book book) {
        // 验证 Token 是否有效
        Result tokenResult = tokenUtil.validateToken(authorizationHeader);
        if (!tokenResult.isSuccess()) {
            return tokenResult; // 如果 Token 无效，返回相应的错误信息
        }

        // 从 Authorization 头中提取 Token
        String token = authorizationHeader.replace("Bearer ", "");

        // 权限验证逻辑
        // 提取用户角色
        String userRole = tokenUtil.getClaimFromToken(token, "userRole");

        System.out.println(userRole);
        if (!"admin".equals(userRole)) {
            return Result.error(403, "只有管理员才能增加书籍");
        }

        try {
            LocalDateTime time = LocalDateTime.now(); // 获取当前时间
            book.setBookUploadtime(time.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))); // 设置书籍上传时间
            // 尝试保存书籍
            boolean isSaved = iBookService.save(book);
            if (isSaved) {
                return Result.success("书籍添加成功");
            } else {
                return Result.error("书籍添加失败");
            }
        } catch (Exception e) {
            System.err.println("Error adding book: " + e.getMessage()); // 打印错误信息
            return Result.error("书籍添加过程中出现错误: " + e.getMessage());
        }
    }

    /**
     * 删除书籍
     *
     * 该方法用于删除指定 ID 的书籍。
     *
     * @param authorizationHeader 请求头中的授权信息，包含 JWT Token
     * @param id 要删除的书籍 ID
     * @return 删除操作的结果
     */
    @DeleteMapping("/delete/{id}")
    public Result deleteBook(@RequestHeader("Authorization") String authorizationHeader, @PathVariable("id") Integer id) {
        // 验证 Token 是否有效
        Result tokenResult = tokenUtil.validateToken(authorizationHeader);
        if (!tokenResult.isSuccess()) {
            return tokenResult; // 如果 Token 无效，返回相应的错误信息
        }

        // 提取用户角色
        String userRole = tokenUtil.getClaimFromToken(authorizationHeader, "userRole");

        if (!"admin".equals(userRole)) {
            return Result.error(403, "只有管理员才能删除书籍");
        }

        boolean isDeleted = iBookService.removeById(id); // 删除书籍
        if (isDeleted) {
            return Result.success("书籍删除成功");
        } else {
            return Result.error("书籍删除失败");
        }
    }

    /**
     * 归还书籍
     *
     * 该方法用于用户归还书籍。
     *
     * @param authorizationHeader 请求头中的授权信息，包含 JWT Token
     * @param book 包含书籍信息的对象
     * @return 归还操作的结果
     */
    @PostMapping("/returnbook")
    public Result returnBook(@RequestHeader("Authorization") String authorizationHeader, @RequestBody @Validated Book book) {
        // 1. 验证 Token 是否有效
        Result tokenResult = tokenUtil.validateToken(authorizationHeader);
        if (!tokenResult.isSuccess()) {
            return tokenResult; // 如果 Token 无效，返回相应的错误信息
        }

        // 2. 从 Token 中提取用户名
        String userName = tokenUtil.getClaimFromToken(authorizationHeader, "userName");
        if (userName == null || userName.isEmpty()) {
            return Result.error(400, "无法从 Token 中提取用户名");
        }

        try {
            // 3. 根据 book_id 或 book_isbn 查找图书
            Book existingBook;
            if (book.getBookId() != null) {
                existingBook = iBookService.getById(book.getBookId());
            } else if (book.getBookIsbn() != null && !book.getBookIsbn().isEmpty()) {
                LambdaQueryWrapper<Book> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(Book::getBookIsbn, book.getBookIsbn());
                existingBook = iBookService.getOne(queryWrapper);

            } else {
                return Result.error(400, "缺少 book_id 或 book_isbn");
            }

            if (existingBook == null) {
                return Result.error(404, "未找到指定的图书");
            }

            // 4. 检查图书是否被当前用户借阅
            if (!userName.equals(existingBook.getBookBorrower())) {
                return Result.error(403, "您没有借阅这本书，无法归还");
            }
            System.out.println(existingBook);
            // 5. 更新图书状态
            LambdaUpdateWrapper<Book> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(Book::getBookId, existingBook.getBookId())
                    .set(Book::getBookStatus, "0") // 设置图书状态为可借
                    .set(Book::getBookBorrower, null) // 清除借阅者信息
                    .set(Book::getBookBorrowtime, null) // 清除借阅时间
                    .set(Book::getBookReturntime, null); // 清除归还时间

            boolean isBookUpdated = iBookService.update(updateWrapper);
            if (!isBookUpdated) {
                return Result.error("图书归还失败，无法更新图书信息");
            }

            // 6. 更新借阅记录
            LambdaQueryWrapper<BorrowRecord> recordQuery = new LambdaQueryWrapper<>();
            recordQuery.eq(BorrowRecord::getRecordBookisbn, existingBook.getBookIsbn())
                    .eq(BorrowRecord::getRecordBorrower, userName)
                    .isNull(BorrowRecord::getRecordRemandtime); // 查找未归还的记录

            BorrowRecord borrowRecord = iRecordService.getOne(recordQuery);
            if (borrowRecord == null) {
                return Result.error("未找到对应的借阅记录");
            }

            // 设置实际归还时间为当前时间
            LocalDateTime now = LocalDateTime.now();
            borrowRecord.setRecordRemandtime(now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

            boolean isRecordUpdated = iRecordService.updateById(borrowRecord);
            if (!isRecordUpdated) {
                return Result.error("图书归还失败，无法更新借阅记录");
            }
            System.out.println("借阅记录更新成功: " + borrowRecord);

            return Result.success("图书归还成功");
        } catch (Exception e) {
            System.err.println("Error returning book: " + e.getMessage());
            return Result.error("图书归还过程中出现错误: " + e.getMessage());
        }
    }

    /**
     * 修改书籍信息
     *
     * 该方法用于修改已有的书籍信息，操作之前会进行 Token 验证和管理员权限校验。
     *
     * @param authorizationHeader 请求头中的授权信息，包含 JWT Token
     * @param book 要修改的书籍对象
     * @return 修改操作的结果
     */
    @PutMapping("/updatebook")
    public Result updateBook(@RequestHeader("Authorization") String authorizationHeader, @RequestBody @Validated Book book) {
        // 验证 Token 是否有效
        Result tokenResult = tokenUtil.validateToken(authorizationHeader);
        if (!tokenResult.isSuccess()) {
            return tokenResult; // 如果 Token 无效，返回相应的错误信息
        }

        // 从 Authorization 头中提取 Token
        String token = authorizationHeader.replace("Bearer ", "");

        // 提取用户角色
        String userRole = tokenUtil.getClaimFromToken(token, "userRole");

        // 检查用户角色是否为管理员
        if (!"admin".equals(userRole)) {
            return Result.error(403, "只有管理员才能修改书籍");
        }

        try {
            // 检查书籍是否存在
            Book existingBook = iBookService.getById(book.getBookId());
            if (existingBook == null) {
                return Result.error(404, "未找到指定的图书");
            }

            // 更新书籍信息
            boolean isUpdated = iBookService.updateById(book);
            if (isUpdated) {
                return Result.success("书籍修改成功");
            } else {
                return Result.error("书籍修改失败");
            }
        } catch (Exception e) {
            System.err.println("Error updating book: " + e.getMessage());
            return Result.error("书籍修改过程中出现错误: " + e.getMessage());
        }
    }

    /**
     * 借阅书籍
     *
     * 该方法用于用户借阅书籍。
     *
     * @param authorizationHeader 请求头中的授权信息，包含 JWT Token
     * @param book 包含书籍信息的对象
     * @return 借阅操作的结果
     */
    @PostMapping("/borrowbook")
    public Result borrowBook(@RequestHeader("Authorization") String authorizationHeader, @RequestBody @Validated Book book) {
        // 1. 验证 Token 是否有效
        Result tokenResult = tokenUtil.validateToken(authorizationHeader);
        if (!tokenResult.isSuccess()) {
            return tokenResult; // 如果 Token 无效，返回相应的错误信息
        }

        // 2. 从 Token 中提取用户名
        String userName = tokenUtil.getClaimFromToken(authorizationHeader, "userName");
        if (userName == null || userName.isEmpty()) {
            return Result.error(400, "无法从 Token 中提取用户名");
        }


        // 查询指定用户名且未归还的图书
        LambdaQueryWrapper<Book> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Book::getBookBorrower, userName)
                .eq(Book::getBookStatus, '1'); // Assuming '1' indicates borrowed

        List<Book> unreturnedBooks = iBookService.list(lambdaQueryWrapper);
        System.out.println(unreturnedBooks.size());
        System.out.println("1111111111111111");
        if (unreturnedBooks.size() >= 5) {
            System.out.println(unreturnedBooks.size());
            return Result.error("你已借超过5本书,请先还书");
        }

        
        try {
            // 3. 根据 book_id 或 book_isbn 查找图书
            Book existingBook;
            if (book.getBookId() != null) {
                existingBook = iBookService.getById(book.getBookId());
            } else if (book.getBookIsbn() != null && !book.getBookIsbn().isEmpty()) {
                LambdaQueryWrapper<Book> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(Book::getBookIsbn, book.getBookIsbn());
                existingBook = iBookService.getOne(queryWrapper);
            } else {
                return Result.error(400, "缺少 book_id 或 book_isbn");
            }

            if (existingBook == null) {
                return Result.error(404, "未找到指定的图书");
            }

            // 4. 检查图书是否可借阅
            if (!"0".equals(existingBook.getBookStatus())) {
                return Result.error(400, "该图书已被借阅");
            }

            // 5. 更新图书状态及借阅信息
            LocalDateTime now = LocalDateTime.now(); // 获取当前时间
            LocalDateTime expectedReturnTime = now.plusMonths(1); // 设置预计归还时间为一个月后

            existingBook.setBookStatus("1"); // 更新图书状态为已借出
            existingBook.setBookBorrower(userName); // 设置借阅者
            existingBook.setBookBorrowtime(now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); // 记录借出时间
            existingBook.setBookReturntime(expectedReturnTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); // 记录预计归还时间

            boolean isBookUpdated = iBookService.updateById(existingBook);
            if (!isBookUpdated) {
                return Result.error("图书借阅失败，无法更新图书信息");
            }

            // 6. 创建借阅记录
            BorrowRecord borrowRecord = new BorrowRecord();
            borrowRecord.setRecordBookname(existingBook.getBookName());
            borrowRecord.setRecordBookisbn(existingBook.getBookIsbn());
            borrowRecord.setRecordBorrower(userName);
            borrowRecord.setRecordBorrowtime(now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            borrowRecord.setRecordRemandtime(null); // 还书时间为空，表示未归还

            boolean isRecordSaved = iRecordService.save(borrowRecord);
            if (!isRecordSaved) {
                return Result.error("图书借阅失败，无法创建借阅记录");
            }

            return Result.success("图书借阅成功");
        } catch (Exception e) {
            System.err.println("Error borrowing book: " + e.getMessage());
            return Result.error("图书借阅过程中出现错误: " + e.getMessage());
        }
    }

}
